package com.ssy.lingxi.marketing.serviceimpl.component.activity;

import cn.hutool.core.collection.CollectionUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.marketing.ActivityTypeEnum;
import com.ssy.lingxi.common.constant.marketing.BelongTypeEnum;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.model.bo.MemberAndRoleIdBO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.common.utils.DateTimeUtil;
import com.ssy.lingxi.marketing.api.model.response.*;
import com.ssy.lingxi.marketing.entity.activity.*;
import com.ssy.lingxi.marketing.model.bo.*;
import com.ssy.lingxi.marketing.model.constant.*;
import com.ssy.lingxi.marketing.repository.ActivityGoodsRepository;
import com.ssy.lingxi.marketing.service.feign.IMemberFeignService;
import com.ssy.lingxi.marketing.service.feign.IProductFeignService;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberFeignBatchVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberFeignUpperMemberVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberFeignRightDetailVO;
import com.ssy.lingxi.product.api.model.request.feign.CommodityPriceRequest;
import com.ssy.lingxi.product.api.model.response.commodity.CommodityOrderResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 活动商品标签计算服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2021/9/2
 */
@Slf4j
@Service
public class ActivityGoodsTagAndPriceComponent {

    @Resource
    private JPAQueryFactory queryFactory;
    @Resource
    private ActivityTagComponent activityTagComponent;
    @Resource
    private ActivityEstimatePriceComponent activityEstimatePriceComponent;
    @Resource
    private ActivityGoodsHandleComponent goodsHandleComponent;
    @Resource
    private ActivityGoodsRepository activityGoodsRepository;
    @Resource
    private IProductFeignService productFeignService;
    @Resource
    private IMemberFeignService memberFeignService;
    @Resource
    private ActivityCheckRuleComponent activityCheckRuleComponent;

    private boolean isKillTime(SecKillBO secKillBO){
        int nowSec=DateTimeUtil.getNowSecOfHHmmss();
        return DateTimeUtil.getNowSecOfHHmmss(secKillBO.getStartTime())<nowSec&&DateTimeUtil.getNowSecOfHHmmss(secKillBO.getEndTime())>nowSec;
    }

    public List<Map<Object, Object>> buildLadders(Integer activityType,ActivityDefinedBO activityDefinedBO,Long activityGoodsId,Long memberId,Long roleId,Long shopId){
        List<Map<Object, Object>> ladders=new ArrayList<>();
        if (ActivityTypeEnum.FULL_QUANTITY.getCode().equals(activityType)) {
            // 满量促销
            FullQuantityBO activityDefined = (FullQuantityBO) activityDefinedBO;
            ladders=activityDefined.getLadderList().stream().map(ladder -> {
                Map<Object, Object> map = new HashMap<>();
                map.put(ladder.getKey(), ladder.getValue());
                return map;
            }).collect(Collectors.toList());

        } else if (ActivityTypeEnum.FULL_MONEY.getCode().equals(activityType)) {
            // 满额促销
            FullMoneyBO activityDefined = (FullMoneyBO) activityDefinedBO;
            ladders=activityDefined.getLadderList().stream().map(ladder -> {
                Map<Object, Object> map = new HashMap<>();
                map.put(ladder.getKey(), ladder.getValue());
                return map;
            }).collect(Collectors.toList());

        } else if (ActivityTypeEnum.GIVE.getCode().equals(activityType)) {
            // 赠送促销
            GiveBO activityDefined = (GiveBO) activityDefinedBO;
            Integer concreteType = this.getConcreteType(activityType, activityDefined.getGiftType(),activityDefined.getGiveType());
            if (GiveGiftTypeEnum.GOODS.getCode().equals(activityDefined.getGiftType())) {
                List<ActivityGoodsSubsidiaryDO> activityGoodsSubsidiaryList = goodsHandleComponent.getActivityGoodsSubsidiaryList(activityGoodsId);
                // 商品详细信息map
                Map<Long, CommodityOrderResponse> commodityMap = this.getGoodsDetailMap(memberId, roleId, shopId, activityGoodsSubsidiaryList);
                // 会员权益参数
                Map<MemberAndRoleIdBO, MemberFeignRightDetailVO> memberRightMap = this.getMemberRightMap(memberId, roleId, activityGoodsSubsidiaryList);
                List<ActivityGoodsSubsidiaryGroupBO> activityGoodsSubsidiaryGroupList = goodsHandleComponent.groupingGoodsSubsidiary(activityGoodsSubsidiaryList);
                ladders=activityGoodsSubsidiaryGroupList.stream().map(goodsSubsidiaryGroupBO -> {
                    Map<Object, Object> map = new HashMap<>();
                    map.put("limitValue", goodsSubsidiaryGroupBO.getLimitValue());

                    List<GoodsSubsidiaryGroupDetail> detailList = goodsSubsidiaryGroupBO.getList().stream()
                            .map(subsidiaryGroupDetailBO -> this.convertGoodsSubsidiaryGroupDetail(subsidiaryGroupDetailBO, activityType, concreteType, commodityMap, memberRightMap))
                            .collect(Collectors.toList());
                    map.put("list", detailList);
                    return map;
                }).collect(Collectors.toList());

            } else if (GiveGiftTypeEnum.COUPON.getCode().equals(activityDefined.getGiftType())) {
                List<ActivityGoodsCouponGroupBO> activityGoodsCouponGroupList = goodsHandleComponent.getActivityGoodsCouponGroupList(activityGoodsId);
                ladders=activityGoodsCouponGroupList.stream().map(goodsCouponGroupBO -> {
                    Map<Object, Object> map = new HashMap<>();
                    map.put("limitValue", goodsCouponGroupBO.getLimitValue());

                    List<GoodsCouponGroupDetail> detailList = goodsCouponGroupBO.getList().stream().map(this::convertGoodsCouponGroupDetail).collect(Collectors.toList());
                    map.put("list", detailList);
                    return map;
                }).collect(Collectors.toList());
            }

        } else if (ActivityTypeEnum.MORE_PIECE.getCode().equals(activityType)) {
            // 多件促销
            MorePieceBO activityDefined = (MorePieceBO) activityDefinedBO;
            ladders=activityDefined.getLadderList().stream().map(ladder -> {
                Map<Object, Object> map = new HashMap<>();
                map.put(ladder.getNum(), ladder.getDiscount());
                return map;
            }).collect(Collectors.toList());

        }else if (ActivityTypeEnum.SWAP.getCode().equals(activityType)) {
            // 换购
            SwapBO activityDefined = (SwapBO) activityDefinedBO;
            Integer concreteType = this.getConcreteType(activityType, activityDefined.getSwapType());
            List<ActivityGoodsSubsidiaryDO> activityGoodsSubsidiaryList = goodsHandleComponent.getActivityGoodsSubsidiaryList(activityGoodsId);
            // 商品详细信息map
            Map<Long, CommodityOrderResponse> commodityMap = this.getGoodsDetailMap(memberId, roleId, shopId, activityGoodsSubsidiaryList);
            // 会员权益参数
            Map<MemberAndRoleIdBO, MemberFeignRightDetailVO> memberRightMap = this.getMemberRightMap(memberId, roleId, activityGoodsSubsidiaryList);

            List<ActivityGoodsSubsidiaryGroupBO> activityGoodsSubsidiaryGroupList = goodsHandleComponent.groupingGoodsSubsidiary(activityGoodsSubsidiaryList);
            ladders=activityGoodsSubsidiaryGroupList.stream().map(goodsCouponGroupBO -> {
                Map<Object, Object> map = new HashMap<>();
                map.put("limitValue", goodsCouponGroupBO.getLimitValue());

                ActivityGoodsSubsidiaryGroupDetailBO subsidiaryGroupDetailBO = goodsCouponGroupBO.getList().size() > 0 ? goodsCouponGroupBO.getList().get(0) : new ActivityGoodsSubsidiaryGroupDetailBO();
                GoodsSubsidiaryGroupDetail detail = this.convertGoodsSubsidiaryGroupDetail(subsidiaryGroupDetailBO, activityType, concreteType, commodityMap, memberRightMap);

                map.put("list", Collections.singletonList(detail));
                return map;
            }).collect(Collectors.toList());
        }
        return ladders;
    }

    /**
     * 处理购物车中sku标签
     * @param memberId 当前会员id
     * @param roleId 当前角色id
     * @param shopId 商城id
     * @param activityGoodsDetailBOList 活动商品
     * @return 返回结果
     */
    public List<GoodsActivityDetail> handleCartSkuTag(Long memberId, Long roleId, Long shopId,List<ActivityGoodsDetailBO> activityGoodsDetailBOList) {
        List<GoodsActivityDetail> goodsActivityDetailList = new ArrayList<>();

        for (ActivityGoodsDetailBO activityGoodsBO : activityGoodsDetailBOList) {
            GoodsActivityDetail activityDetail = new GoodsActivityDetail();
            activityDetail.setActivityId(activityGoodsBO.getActivityBO().getActivityId());
            activityDetail.setBelongType(activityGoodsBO.getBelongType());
            activityDetail.setActivityType(activityGoodsBO.getActivityBO().getActivityType());
            activityDetail.setStartTime(DateTimeUtil.formatDate(DateTimeUtil.toLocalDateTime(activityGoodsBO.getActivityBO().getStartTime())));
            activityDetail.setEndTime(DateTimeUtil.formatDate(DateTimeUtil.toLocalDateTime(activityGoodsBO.getActivityBO().getEndTime())));
            activityDetail.setCanUseCoupon(activityCheckRuleComponent.checkCanUserCoupon(activityGoodsBO) ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode());
            activityDetail.setRestrictNum(activityGoodsBO.getRestrictNum());

            ActivityGoodsTagBO activityGoodsTagBO = activityTagComponent.handActivityGoodsTag(activityGoodsBO);

            activityDetail.setPreferentialTag(activityGoodsTagBO.getPreferentialTag());

            Integer activityType = activityGoodsBO.getActivityBO().getActivityType();
            if (ActivityTypeEnum.SPECIAL_OFFER.getCode().equals(activityType)) {
                // 特价促销
                activityDetail.setPreferentialTagDescs(Collections.singletonList(activityGoodsTagBO.getPreferentialTagDesc()));

            } else if (ActivityTypeEnum.PLUMMET.getCode().equals(activityType)) {
                // 直降促销
                activityDetail.setPreferentialTagDescs(Collections.singletonList(activityGoodsTagBO.getPreferentialTagDesc()));

            } else if (ActivityTypeEnum.DISCOUNT.getCode().equals(activityType)) {
                // 折扣促销
                activityDetail.setPreferentialTagDescs(Collections.singletonList(activityGoodsTagBO.getPreferentialTagDesc()));

            } else if (ActivityTypeEnum.FULL_QUANTITY.getCode().equals(activityType)) {
                // 满量促销
                FullQuantityBO activityDefined = (FullQuantityBO) activityGoodsBO.getActivityBO().getActivityDefined();
                activityDetail.setConcreteType(this.getConcreteType(activityType, activityDefined.getType()));
                activityDetail.setLadders(activityDefined.getLadderList().stream().map(ladder -> {
                    Map<Object, Object> map = new HashMap<>();
                    map.put(ladder.getKey(), ladder.getValue());
                    return map;
                }).collect(Collectors.toList()));
                activityDetail.setPreferentialTagDescs(Arrays.asList(activityGoodsTagBO.getPreferentialLadderList().toArray()));

            } else if (ActivityTypeEnum.FULL_MONEY.getCode().equals(activityType)) {
                // 满额促销
                FullMoneyBO activityDefined = (FullMoneyBO) activityGoodsBO.getActivityBO().getActivityDefined();
                Integer concreteType = this.getConcreteType(activityType, activityDefined.getType());
                activityDetail.setConcreteType(concreteType);
                activityDetail.setLadders(activityDefined.getLadderList().stream().map(ladder -> {
                    Map<Object, Object> map = new HashMap<>();
                    map.put(ladder.getKey(), ladder.getValue());
                    return map;
                }).collect(Collectors.toList()));
                activityDetail.setPreferentialTagDescs(Arrays.asList(activityGoodsTagBO.getPreferentialLadderList().toArray()));

            } else if (ActivityTypeEnum.GIVE.getCode().equals(activityType)) {
                // 赠送促销
                GiveBO activityDefined = (GiveBO) activityGoodsBO.getActivityBO().getActivityDefined();
                Integer concreteType = this.getConcreteType(activityType, activityDefined.getGiftType(),activityDefined.getGiveType());
                activityDetail.setConcreteType(concreteType);
                if (GiveGiftTypeEnum.GOODS.getCode().equals(activityDefined.getGiftType())) {
                    List<ActivityGoodsSubsidiaryDO> activityGoodsSubsidiaryList = goodsHandleComponent.getActivityGoodsSubsidiaryList(activityGoodsBO.getId());
                    // 商品详细信息map
                    Map<Long, CommodityOrderResponse> commodityMap = this.getGoodsDetailMap(memberId, roleId, shopId, activityGoodsSubsidiaryList);
                    // 会员权益参数
                    Map<MemberAndRoleIdBO, MemberFeignRightDetailVO> memberRightMap = this.getMemberRightMap(memberId, roleId, activityGoodsSubsidiaryList);
                    List<ActivityGoodsSubsidiaryGroupBO> activityGoodsSubsidiaryGroupList = goodsHandleComponent.groupingGoodsSubsidiary(activityGoodsSubsidiaryList);
                    activityDetail.setLadders(activityGoodsSubsidiaryGroupList.stream().map(goodsSubsidiaryGroupBO -> {
                        Map<Object, Object> map = new HashMap<>();
                        map.put("limitValue", goodsSubsidiaryGroupBO.getLimitValue());

                        List<GoodsSubsidiaryGroupDetail> detailList = goodsSubsidiaryGroupBO.getList().stream()
                                .map(subsidiaryGroupDetailBO -> this.convertGoodsSubsidiaryGroupDetail(subsidiaryGroupDetailBO, activityType, concreteType, commodityMap, memberRightMap))
                                .collect(Collectors.toList());
                        map.put("list", detailList);
                        return map;
                    }).collect(Collectors.toList()));

                    activityDetail.setPreferentialTagDescs(Arrays.asList(activityGoodsTagBO.getPreferentialLadderList().toArray()));

                } else if (GiveGiftTypeEnum.COUPON.getCode().equals(activityDefined.getGiftType())) {
                    List<ActivityGoodsCouponGroupBO> activityGoodsCouponGroupList = goodsHandleComponent.getActivityGoodsCouponGroupList(activityGoodsBO.getId());
                    activityDetail.setLadders(activityGoodsCouponGroupList.stream().map(goodsCouponGroupBO -> {
                        Map<Object, Object> map = new HashMap<>();
                        map.put("limitValue", goodsCouponGroupBO.getLimitValue());

                        List<GoodsCouponGroupDetail> detailList = goodsCouponGroupBO.getList().stream().map(this::convertGoodsCouponGroupDetail).collect(Collectors.toList());
                        map.put("list", detailList);
                        return map;
                    }).collect(Collectors.toList()));

                    activityDetail.setPreferentialTagDescs(Arrays.asList(activityGoodsTagBO.getPreferentialLadderList().toArray()));
                }

            } else if (ActivityTypeEnum.MORE_PIECE.getCode().equals(activityType)) {
                // 多件促销
                MorePieceBO activityDefined = (MorePieceBO) activityGoodsBO.getActivityBO().getActivityDefined();
                activityDetail.setLadders(activityDefined.getLadderList().stream().map(ladder -> {
                    Map<Object, Object> map = new HashMap<>();
                    map.put(ladder.getNum(), ladder.getDiscount());
                    return map;
                }).collect(Collectors.toList()));
                activityDetail.setPreferentialTagDescs(Arrays.asList(activityGoodsTagBO.getPreferentialLadderList().toArray()));

            } else if (ActivityTypeEnum.COMBINATION.getCode().equals(activityType)) {
                // 组合促销
                CombinationBO activityDefined = (CombinationBO) activityGoodsBO.getActivityBO().getActivityDefined();
                activityDetail.setCombination(new GoodsActivityDetail.Combination(activityDefined.getNum(), activityDefined.getPrice()));
                activityDetail.setPreferentialTagDescs(Collections.singletonList(activityGoodsTagBO.getPreferentialTagDesc()));

            } else if (ActivityTypeEnum.SWAP.getCode().equals(activityType)) {
                // 换购
                SwapBO activityDefined = (SwapBO) activityGoodsBO.getActivityBO().getActivityDefined();
                Integer concreteType = this.getConcreteType(activityType, activityDefined.getSwapType());
                activityDetail.setConcreteType(concreteType);
                List<ActivityGoodsSubsidiaryDO> activityGoodsSubsidiaryList = goodsHandleComponent.getActivityGoodsSubsidiaryList(activityGoodsBO.getId());
                // 商品详细信息map
                Map<Long, CommodityOrderResponse> commodityMap = this.getGoodsDetailMap(memberId, roleId, shopId, activityGoodsSubsidiaryList);
                // 会员权益参数
                Map<MemberAndRoleIdBO, MemberFeignRightDetailVO> memberRightMap = this.getMemberRightMap(memberId, roleId, activityGoodsSubsidiaryList);

                List<ActivityGoodsSubsidiaryGroupBO> activityGoodsSubsidiaryGroupList = goodsHandleComponent.groupingGoodsSubsidiary(activityGoodsSubsidiaryList);
                activityDetail.setLadders(activityGoodsSubsidiaryGroupList.stream().map(goodsCouponGroupBO -> {
                    Map<Object, Object> map = new HashMap<>();
                    map.put("limitValue", goodsCouponGroupBO.getLimitValue());

                    ActivityGoodsSubsidiaryGroupDetailBO subsidiaryGroupDetailBO = goodsCouponGroupBO.getList().size() > 0 ? goodsCouponGroupBO.getList().get(0) : new ActivityGoodsSubsidiaryGroupDetailBO();
                    GoodsSubsidiaryGroupDetail detail = this.convertGoodsSubsidiaryGroupDetail(subsidiaryGroupDetailBO, activityType, concreteType, commodityMap, memberRightMap);

                    map.put("list", Collections.singletonList(detail));
                    return map;
                }).collect(Collectors.toList()));

                activityDetail.setPreferentialTagDescs(Arrays.asList(activityGoodsTagBO.getPreferentialLadderList().toArray()));
            }else if (ActivityTypeEnum.SEC_KILL.getCode().equals(activityType)) {
                // 秒杀
                SecKillBO secKillBO = (SecKillBO) activityGoodsBO.getActivityBO().getActivityDefined();
                activityDetail.setPreferentialTagDescs(Collections.singletonList(activityGoodsTagBO.getPreferentialTagDesc()));
                Map<String,Object> specialMap=new HashMap<>();
                specialMap.put("startTime",secKillBO.getStartTime());
                specialMap.put("endTime",secKillBO.getEndTime());
                //秒杀倒计时(秒)
                if(isKillTime(secKillBO)) {
                    specialMap.put("countdown", DateTimeUtil.offsetNowSecond(secKillBO.getEndTime()));
                }
                activityDetail.setSpecialMap(specialMap);
            }
            // 参与活动的商品
            List<ActivityGoodsDO> queryGoodsList = activityGoodsRepository.findByBelongTypeAndActivityId(activityGoodsBO.getBelongType(), activityGoodsBO.getActivityBO().getActivityId());
            activityDetail.setActivityGoods(queryGoodsList.stream().map(e -> {
                ActivityParticipateGoods activityGoods = new ActivityParticipateGoods();
                activityGoods.setProductId(e.getProductId());
                activityGoods.setSkuId(e.getSkuId());
                return activityGoods;
            }).collect(Collectors.toList()));

            goodsActivityDetailList.add(activityDetail);
        }

        return goodsActivityDetailList;
    }

    /**
     * 商品列表 - 处理商品标签
     * @param goodsList 活动商品
     * @return 返回结果
     */
    public List<ActivityGoodsProductBO> handProductTag(List<ActivityGoodsDetailBO> goodsList) {
        if (CollectionUtils.isEmpty(goodsList)) {
            return new ArrayList<>();
        }

        // productId - activityGoods
        Map<Long, List<ActivityGoodsDetailBO>> productBOMap = goodsList.stream().collect(Collectors.groupingBy(ActivityGoodsDetailBO::getProductId));

        List<ActivityGoodsProductBO> activityGoodsProductBOList = productBOMap.entrySet().stream().map(entry -> {
            ActivityGoodsProductBO goodsProductBO = new ActivityGoodsProductBO();
            goodsProductBO.setProductId(entry.getKey());
            List<ActivityGoodsSkuBO> goodsSkuBOList = this.handSkuTag(entry.getValue());
            goodsProductBO.setSkuList(goodsSkuBOList);
            return goodsProductBO;
        }).collect(Collectors.toList());

        activityGoodsProductBOList.forEach(e -> {
            // 最优惠价格
            BigDecimal preferentialPrice = e.getSkuList().stream().map(ActivityGoodsSkuBO::getSkuPreferentialPrice).min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
            e.setProductPreferentialPrice(preferentialPrice);
            // 标签集合
            List<ActivityGoodsTagBO> tagList = e.getSkuList().stream().flatMap(sku -> sku.getTagList().stream()).collect(Collectors.toList());
            e.setTotalTagList(tagList);
        });

        return activityGoodsProductBOList;
    }

    /**
     * 商品列表 - 处理sku标签和预估价
     * @param goodsList 活动商品
     * @return 返回结果
     */
    public List<ActivityGoodsSkuBO> handSkuTag(List<ActivityGoodsDetailBO> goodsList) {
        if (CollectionUtils.isEmpty(goodsList)) {
            return new ArrayList<>();
        }

        // skuId - activityGoods
        Map<Long, List<ActivityGoodsDetailBO>> skuBOMap = goodsList.stream().collect(Collectors.groupingBy(ActivityGoodsDetailBO::getSkuId));

        List<ActivityGoodsSkuBO> goodsSkuBOList = skuBOMap.entrySet().stream().map(entry -> {
            ActivityGoodsSkuBO activityGoodsSkuBO = new ActivityGoodsSkuBO();
            activityGoodsSkuBO.setSkuId(entry.getKey());

            // 活动最低价
            BigDecimal promotionPrice = activityEstimatePriceComponent.calPromotionPriceList(entry.getValue()).stream().min(Comparator.comparing(e -> e)).orElse(BigDecimal.ZERO);
            activityGoodsSkuBO.setPromotionPrice(promotionPrice);

            // sku优惠价
            BigDecimal minEstimatePrice = activityEstimatePriceComponent.calEstimatePriceList(entry.getValue()).stream().min(Comparator.comparing(e -> e)).orElse(BigDecimal.ZERO);
            activityGoodsSkuBO.setSkuPreferentialPrice(minEstimatePrice);

            // sku活动标签
            List<ActivityGoodsTagBO> goodsTagBOList = activityTagComponent.handActivityGoodsTag(entry.getValue());
            activityGoodsSkuBO.setTagList(goodsTagBOList);

            // 是否可用优惠券
            activityGoodsSkuBO.setCanUesCoupon(activityCheckRuleComponent.checkGoodsTagCanUserCoupon(goodsTagBOList) ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode());

            return activityGoodsSkuBO;
        }).collect(Collectors.toList());

        return goodsSkuBOList;
    }

    /**
     * 获取ConcreteType
     * 依前端要求, 增加concreteType返回
     * @param activityType 活动类型
     * @param defineType   活动定义类型
     * @return 1-满量减,2-满量折,3-满额减,4-满额折,5-赠商品,6-赠优惠卷 7-满额换购 8-买商品换购
     *
     */
    public Integer getConcreteType(Integer activityType, Integer defineType) {
        return getConcreteType(activityType,defineType,null);
    }

    /**
     * 获取ConcreteType
     * 依前端要求, 增加concreteType返回
     * @param activityType 活动类型
     * @param defineType   活动定义类型
     * @return 1-满量减,2-满量折,3-满额减,4-满额折,5-赠商品,6-赠优惠卷 7-满额换购 8-买商品换购
     *
     */
    public Integer getConcreteType(Integer activityType, Integer defineType,Integer giveType) {
        if (activityType.equals(ActivityTypeEnum.FULL_QUANTITY.getCode())) {
            if (FullQuantityTypeEnum.REDUCTION.getCode().equals(defineType)) {
                return 1;
            }
            if (FullQuantityTypeEnum.DISCOUNT.getCode().equals(defineType)) {
                return 2;
            }
        } else if (activityType.equals(ActivityTypeEnum.FULL_MONEY.getCode())) {
            if (FullMoneyTypeEnum.REDUCTION.getCode().equals(defineType)) {
                return 3;
            }
            if (FullQuantityTypeEnum.DISCOUNT.getCode().equals(defineType)) {
                return 4;
            }
        } else if (activityType.equals(ActivityTypeEnum.GIVE.getCode())) {
            if(GiveTypeEnum.FULL_MONEY.getCode().equals(giveType)) {
                if (GiveGiftTypeEnum.GOODS.getCode().equals(defineType)) {
                    return 5;
                }
                if (GiveGiftTypeEnum.COUPON.getCode().equals(defineType)) {
                    return 6;
                }
            }else if(GiveTypeEnum.BUY_GOODS.getCode().equals(giveType)){
                if (GiveGiftTypeEnum.GOODS.getCode().equals(defineType)) {
                    return 9;
                }
                if (GiveGiftTypeEnum.COUPON.getCode().equals(defineType)) {
                    return 10;
                }
            }
        } else if (activityType.equals(ActivityTypeEnum.SWAP.getCode())) {
            if (SwapTypeEnum.FULL_MONEY.getCode().equals(defineType)) {
                return 7;
            }
            if (SwapTypeEnum.BUY_GOODS.getCode().equals(defineType)) {
                return 8;
            }
        }

        return null;
    }

    /**
     * 获取商品的最大优惠价格
     * 备注: 由yzc迁移代码
     * @author fhj
     * @param shopId 商城ID
     * @param productIdList 商品ID集合
     */
    public List<ProductTagResp> getPreferentialPrice(Long shopId, List<Long> productIdList) {
        //根据商城id与商品id获取平台活动商品和商家活动商品
        List<ActivityGoodsBO> ptActivityGoodsBO = getPtActivityGoodsByProductId(shopId, productIdList);
        List<ActivityGoodsBO> mcActivityGoodsBO = getMcActivityGoodsByProductId(shopId, productIdList);

        //校验
        if (CollectionUtil.isEmpty(ptActivityGoodsBO) && CollectionUtil.isEmpty(mcActivityGoodsBO)) {
            return null;
        }

        //添加到一起
        ptActivityGoodsBO.addAll(mcActivityGoodsBO);

        //以商品ID分组
        Map<Long, List<ActivityGoodsBO>> productMap = ptActivityGoodsBO.stream().collect(Collectors.groupingBy(e -> e.getProductId()));

        //封装
        List<ProductTagResp> productTagRespList = new ArrayList<>();
        productMap.keySet().forEach(key -> {
            //获取每个商品对应的活动商品
            List<ActivityGoodsBO> activityGoodsList = productMap.get(key);

            //封装商品ID和商品最大优惠价格
            ProductTagResp productTagResp = new ProductTagResp();
            productTagResp.setProductId(key);
            setPreferentialPrice(productTagResp, activityGoodsList);
            productTagRespList.add(productTagResp);
        });

        return productTagRespList;
    }

    /**
     * 根据商品ID获取平台活动商品
     * 备注: 由yzc迁移代码
     * @author fhj
     * @param shopId 商城ID
     * @param productIdList 商品ID集合
     */
    private List<ActivityGoodsBO> getPtActivityGoodsByProductId(Long shopId, List<Long> productIdList) {
        QActivityGoodsDO activityGoodsDO = QActivityGoodsDO.activityGoodsDO;
        QPlatformActivityDO platformActivityDO = QPlatformActivityDO.platformActivityDO;
        QActivityShopDO activityShopDO = QActivityShopDO.activityShopDO;

        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(activityGoodsDO.belongType.eq(BelongTypeEnum.PLATFORM.getCode()));
        predicates.and(activityGoodsDO.productId.in(productIdList));
        predicates.and(activityShopDO.shopId.eq(shopId));
        predicates.and(platformActivityDO.outerStatus.eq(PlatformActivityOuterStatusEnum.ONGOING.getCode()));
        predicates.and(platformActivityDO.startTime.loe(System.currentTimeMillis()));
        predicates.and(platformActivityDO.endTime.goe(System.currentTimeMillis()));

        JPAQuery<ActivityGoodsBO> queryJpaQuery = queryFactory.select(Projections.bean(ActivityGoodsBO.class,
                activityGoodsDO.id,
                activityGoodsDO.activityId,
                activityGoodsDO.belongType,
                platformActivityDO.activityType,
                platformActivityDO.activityDefined,
                platformActivityDO.startTime,
                platformActivityDO.endTime,
                activityGoodsDO.memberId,
                activityGoodsDO.roleId,
                activityGoodsDO.productId,
                activityGoodsDO.skuId,
                activityGoodsDO.price,
                activityGoodsDO.plummetPrice,
                activityGoodsDO.activityPrice,
                activityGoodsDO.deductionPrice,
                activityGoodsDO.discount,
                activityGoodsDO.restrictNum,
                activityGoodsDO.restrictTotalNum))
                .from(activityGoodsDO)
                .leftJoin(platformActivityDO).on(platformActivityDO.id.eq(activityGoodsDO.activityId))
                .leftJoin(activityShopDO).on(activityShopDO.activityId.eq(platformActivityDO.id).and(activityShopDO.belongType.eq(BelongTypeEnum.PLATFORM.getCode())));

        queryJpaQuery.where(predicates);

        return queryJpaQuery.orderBy(platformActivityDO.createTime.desc()).fetch();
    }

    /**
     * 根据商品ID获取商家活动商品
     * 备注: 由yzc迁移代码
     * @author fhj
     * @param shopId 商城ID
     * @param productIdList 商品ID集合
     */
    private List<ActivityGoodsBO> getMcActivityGoodsByProductId(Long shopId, List<Long> productIdList) {
        QActivityGoodsDO activityGoodsDO = QActivityGoodsDO.activityGoodsDO;
        QMerchantActivityDO merchantActivityDO = QMerchantActivityDO.merchantActivityDO;
        QActivityShopDO activityShopDO = QActivityShopDO.activityShopDO;

        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(activityGoodsDO.belongType.eq(BelongTypeEnum.MERCHANT.getCode()));
        predicates.and(activityGoodsDO.productId.in(productIdList));
        predicates.and(activityShopDO.shopId.eq(shopId));
        predicates.and(merchantActivityDO.innerStatus.eq(MerchantActivityInnerStatusEnum.ONGOING.getCode()));
        predicates.and(merchantActivityDO.startTime.loe(System.currentTimeMillis()));
        predicates.and(merchantActivityDO.endTime.goe(System.currentTimeMillis()));

        JPAQuery<ActivityGoodsBO> queryJpaQuery = queryFactory.select(Projections.bean(ActivityGoodsBO.class,
                activityGoodsDO.id,
                activityGoodsDO.activityId,
                activityGoodsDO.belongType,
                merchantActivityDO.activityType,
                merchantActivityDO.activityDefined,
                merchantActivityDO.startTime,
                merchantActivityDO.endTime,
                activityGoodsDO.memberId,
                activityGoodsDO.roleId,
                activityGoodsDO.productId,
                activityGoodsDO.skuId,
                activityGoodsDO.price,
                activityGoodsDO.plummetPrice,
                activityGoodsDO.activityPrice,
                activityGoodsDO.deductionPrice,
                activityGoodsDO.discount,
                activityGoodsDO.restrictNum,
                activityGoodsDO.restrictTotalNum))
                .from(activityGoodsDO)
                .leftJoin(merchantActivityDO).on(merchantActivityDO.id.eq(activityGoodsDO.activityId))
                .leftJoin(activityShopDO).on(activityShopDO.activityId.eq(merchantActivityDO.id).and(activityShopDO.belongType.eq(BelongTypeEnum.PLATFORM.getCode())));

        queryJpaQuery.where(predicates);

        return queryJpaQuery.orderBy(merchantActivityDO.createTime.desc()).fetch();
    }

    /**
     * 封装商品最大优惠价格
     * 备注: 由yzc迁移代码
     * @author fhj
     * @param resp 返回实体
     * @param list 商品对应的活动商品
     * */
    private void setPreferentialPrice(ProductTagResp resp, List<ActivityGoodsBO> list) {
        //按活动类型正序排序（先计算特价、直降、折扣促销后再去计算满减满额促销）
        list = list.stream().sorted(Comparator.comparing(ActivityGoodsBO::getActivityType)).collect(Collectors.toList());

        //计算商品最大优惠价格
        list.forEach(activityGoods -> {
            //特价促销/直降促销/折扣促销/拼团/砍价/秒杀（拿活动价格）
            if (activityGoods.getActivityType().equals(ActivityTypeEnum.SPECIAL_OFFER.getCode())
                    || activityGoods.getActivityType().equals(ActivityTypeEnum.PLUMMET.getCode())
                    || activityGoods.getActivityType().equals(ActivityTypeEnum.DISCOUNT.getCode())
                    || activityGoods.getActivityType().equals(ActivityTypeEnum.GROUP_PURCHASE.getCode())
                    || activityGoods.getActivityType().equals(ActivityTypeEnum.BARGAIN.getCode())
                    || activityGoods.getActivityType().equals(ActivityTypeEnum.SEC_KILL.getCode())) {
                resp.setPreferentialPrice(activityGoods.getActivityPrice());
            }
            //满量促销（如果该活动商品存在允许叠加活动的话，先计算特价、直降、折扣促销再算满量促销）
            if (activityGoods.getActivityType().equals(ActivityTypeEnum.FULL_QUANTITY.getCode())) {
                FullQuantityBO fullQuantityBO = (FullQuantityBO) activityGoods.getActivityDefined();
                Stream<BigDecimal> stream = fullQuantityBO.getLadderList().stream().map(FullQuantityBO.LadderBO::getValue);
                if (fullQuantityBO.getType().equals(FullQuantityTypeEnum.REDUCTION.getCode())) {
                    BigDecimal reduction = stream.max(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
                    if (resp.getPreferentialPrice() != null) {
                        resp.setPreferentialPrice(resp.getPreferentialPrice().subtract(reduction));
                    } else {
                        resp.setPreferentialPrice(activityGoods.getPrice().subtract(reduction));
                    }
                } else if (fullQuantityBO.getType().equals(FullQuantityTypeEnum.DISCOUNT.getCode())) {
                    BigDecimal discount = stream.min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
                    if (resp.getPreferentialPrice() != null) {
                        resp.setPreferentialPrice(resp.getPreferentialPrice().multiply(discount));
                    } else {
                        resp.setPreferentialPrice(activityGoods.getPrice().multiply(discount));
                    }
                }
            }
            //满额促销（如果该活动商品存在允许叠加活动的话，先计算特价、直降、折扣促销再算满额促销）
            if (activityGoods.getActivityType().equals(ActivityTypeEnum.FULL_MONEY.getCode())) {
                FullMoneyBO fullMoneyBO = (FullMoneyBO) activityGoods.getActivityDefined();
                Stream<BigDecimal> stream = fullMoneyBO.getLadderList().stream().map(FullMoneyBO.LadderBO::getValue);
                if (fullMoneyBO.getType().equals(FullMoneyTypeEnum.REDUCTION.getCode())) {
                    BigDecimal reduction = stream.max(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
                    if (resp.getPreferentialPrice() != null) {
                        resp.setPreferentialPrice(resp.getPreferentialPrice().subtract(reduction));
                    } else {
                        resp.setPreferentialPrice(activityGoods.getPrice().subtract(reduction));
                    }
                } else if (fullMoneyBO.getType().equals(FullMoneyTypeEnum.DISCOUNT.getCode())) {
                    BigDecimal discount = stream.min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
                    if (resp.getPreferentialPrice() != null) {
                        resp.setPreferentialPrice(resp.getPreferentialPrice().multiply(discount));
                    } else {
                        resp.setPreferentialPrice(activityGoods.getPrice().multiply(discount));
                    }
                }
            }
            //多件促销（拿优惠阶梯最小的折扣）
            if (activityGoods.getActivityType().equals(ActivityTypeEnum.MORE_PIECE.getCode())) {
                MorePieceBO morePieceBO = (MorePieceBO) activityGoods.getActivityDefined();
                BigDecimal discount = morePieceBO.getLadderList().stream().map(MorePieceBO.LadderBO::getDiscount).min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
                resp.setPreferentialPrice(activityGoods.getPrice().multiply(discount));
            }
            //组合促销（拿优惠阶梯最小的折扣）预估到手价 = 组合价 * (商品单价 / (商品单价 * 优惠数量))
            if (activityGoods.getActivityType().equals(ActivityTypeEnum.COMBINATION.getCode())) {
                CombinationBO combinationBO = (CombinationBO) activityGoods.getActivityDefined();
                BigDecimal num = BigDecimal.valueOf(combinationBO.getNum());
                BigDecimal price = combinationBO.getPrice();
                BigDecimal result = price.multiply(activityGoods.getPrice().divide((activityGoods.getPrice().multiply(num)), 2, RoundingMode.HALF_UP));
                resp.setPreferentialPrice(result);
            }
            //赠送促销、换购、预售、套餐、试用（暂不计算）
            if (activityGoods.getActivityType().equals(ActivityTypeEnum.GIVE.getCode())
                    || activityGoods.getActivityType().equals(ActivityTypeEnum.SWAP.getCode())
                    || activityGoods.getActivityType().equals(ActivityTypeEnum.PRE_SALE.getCode())
                    || activityGoods.getActivityType().equals(ActivityTypeEnum.SET_MEAL.getCode())
                    || activityGoods.getActivityType().equals(ActivityTypeEnum.ATTEMPT.getCode())) {
                resp.setPreferentialPrice(activityGoods.getPrice());
            }
        });
    }

    private GoodsSubsidiaryGroupDetail convertGoodsSubsidiaryGroupDetail(ActivityGoodsSubsidiaryGroupDetailBO subsidiaryGroupDetailBO, Integer activityType, Integer concreteType, Map<Long, CommodityOrderResponse> commodityMap, Map<MemberAndRoleIdBO, MemberFeignRightDetailVO> memberRightMap) {
        GoodsSubsidiaryGroupDetail detail = new GoodsSubsidiaryGroupDetail();
        detail.setId(subsidiaryGroupDetailBO.getId());
        detail.setProductId(subsidiaryGroupDetailBO.getProductId());
        detail.setSkuId(subsidiaryGroupDetailBO.getSkuId());
        detail.setProductName(subsidiaryGroupDetailBO.getProductName());
        detail.setCategory(subsidiaryGroupDetailBO.getCategory());
        detail.setBrand(subsidiaryGroupDetailBO.getBrand());
        detail.setUnit(subsidiaryGroupDetailBO.getUnit());
        detail.setPrice(subsidiaryGroupDetailBO.getPrice());
        detail.setSwapPrice(subsidiaryGroupDetailBO.getSwapPrice());
        detail.setNum(subsidiaryGroupDetailBO.getNum());
        detail.setProductImgUrl(subsidiaryGroupDetailBO.getProductImgUrl());

        detail.setActivityType(activityType);
        detail.setConcreteType(concreteType);

        CommodityOrderResponse commodityOrderResponse = commodityMap.get(subsidiaryGroupDetailBO.getSkuId());
        if (Objects.nonNull(commodityOrderResponse)) {
            detail.setAttribute(commodityOrderResponse.getAttribute());
            detail.setMinOrder(commodityOrderResponse.getMinOrder());
            detail.setPriceType(commodityOrderResponse.getPriceType());
            if (Objects.isNull(commodityOrderResponse.getIsMemberPrice())) {
                detail.setIsMemberPrice(false);
            } else {
                detail.setIsMemberPrice(commodityOrderResponse.getIsMemberPrice());
                if (commodityOrderResponse.getIsMemberPrice()) {
                    MemberFeignRightDetailVO memberFeignRightDetailVO = memberRightMap.get(new MemberAndRoleIdBO(commodityOrderResponse.getMemberId(), commodityOrderResponse.getMemberRoleId()));
                    if (Objects.nonNull(memberFeignRightDetailVO)) {
                        detail.setParameter(memberFeignRightDetailVO.getParameter());
                    }
                }
            }

            detail.setMin(commodityOrderResponse.getMin());
            detail.setMax(commodityOrderResponse.getMax());
            detail.setTaxRate(commodityOrderResponse.getTaxRate());
            detail.setMemberId(commodityOrderResponse.getMemberId());
            detail.setMemberName(commodityOrderResponse.getMemberName());
            detail.setMemberRoleId(commodityOrderResponse.getMemberRoleId());
            detail.setMemberRoleName(commodityOrderResponse.getMemberRoleName());
            detail.setUnitPrice(commodityOrderResponse.getUnitPrice());
            GoodsSubsidiaryGroupDetail.LogisticsResponse logisticsResponse = new GoodsSubsidiaryGroupDetail.LogisticsResponse();
            BeanUtils.copyProperties(commodityOrderResponse.getLogistics(), logisticsResponse);
            detail.setLogistics(logisticsResponse);
            detail.setType(commodityOrderResponse.getType());
            detail.setIsPublish(commodityOrderResponse.getIsPublish());
            detail.setCommodityUnitPriceAndPicId(commodityOrderResponse.getCommodityUnitPriceAndPicId());
            detail.setUpperMemberId(commodityOrderResponse.getUpperMemberId());
            detail.setUpperMemberName(commodityOrderResponse.getUpperMemberName());
            detail.setUpperMemberRoleId(commodityOrderResponse.getUpperMemberRoleId());
            detail.setUpperMemberRoleName(commodityOrderResponse.getUpperMemberRoleName());
        }


        return detail;
    }

    private GoodsCouponGroupDetail convertGoodsCouponGroupDetail(ActivityGoodsCouponGroupDetailBO goodsCouponGroupDetailBO) {
        GoodsCouponGroupDetail detail = new GoodsCouponGroupDetail();
        detail.setId(goodsCouponGroupDetailBO.getId());
        detail.setActivityGoodsId(goodsCouponGroupDetailBO.getActivityGoodsId());
        detail.setNum(goodsCouponGroupDetailBO.getNum());
        detail.setCouponId(goodsCouponGroupDetailBO.getCouponId());
        detail.setCouponName(goodsCouponGroupDetailBO.getCouponName());
        detail.setType(goodsCouponGroupDetailBO.getType());
        detail.setTypeName(goodsCouponGroupDetailBO.getTypeName());
        detail.setDenomination(goodsCouponGroupDetailBO.getDenomination());
        detail.setGetWay(goodsCouponGroupDetailBO.getGetWay());
        detail.setGetWayName(goodsCouponGroupDetailBO.getGetWayName());
        detail.setUseConditionMoney(goodsCouponGroupDetailBO.getUseConditionMoney());
        detail.setEffectiveType(goodsCouponGroupDetailBO.getEffectiveType());
        detail.setEffectiveTypeName(goodsCouponGroupDetailBO.getEffectiveTypeName());
        detail.setEffectiveTimeStart(goodsCouponGroupDetailBO.getEffectiveTimeStart());
        detail.setEffectiveTimeEnd(goodsCouponGroupDetailBO.getEffectiveTimeEnd());
        detail.setInvalidDay(goodsCouponGroupDetailBO.getInvalidDay());
        return detail;
    }

    private Map<Long, CommodityOrderResponse> getGoodsDetailMap(Long memberId, Long roleId, Long shopId, List<ActivityGoodsSubsidiaryDO> activityGoodsSubsidiaryList) {
        Map<Long, CommodityOrderResponse> commodityMap = Collections.emptyMap();
        if (!CollectionUtils.isEmpty(activityGoodsSubsidiaryList)) {
            // 查询商品请求类
            CommodityPriceRequest commodityPriceRequest = new CommodityPriceRequest();
            // 商品类型
            ActivityGoodsSubsidiaryDO goodsSubsidiaryDO = activityGoodsSubsidiaryList.get(0);
            if (MemberTypeEnum.MERCHANT.getCode().equals(goodsSubsidiaryDO.getMemberType())
                    || MemberTypeEnum.MERCHANT_PERSONAL.getCode().equals(goodsSubsidiaryDO.getMemberType())) {
                commodityPriceRequest.setCommodityType(1);
            } else {
                commodityPriceRequest.setCommodityType(2);
            }
            // 商品skuId集合
            List<Long> skuIdList = activityGoodsSubsidiaryList.stream().map(ActivityGoodsSubsidiaryDO::getSkuId).collect(Collectors.toList());
            commodityPriceRequest.setCommoditySkuIdList(skuIdList);
            commodityPriceRequest.setMemberId(memberId);
            commodityPriceRequest.setMemberRoleId(roleId);
            commodityPriceRequest.setShopId(shopId);

            List<CommodityOrderResponse> commodityOrderResponseList = productFeignService.getCommodityListByOrder(commodityPriceRequest);
            commodityMap = Optional.ofNullable(commodityOrderResponseList).map(list ->
                    list.stream().collect(Collectors.toMap(e -> e.getId(), e -> e, (e1, e2) -> e2)))
                    .orElse(new HashMap<>());
        }

        return commodityMap;
    }

    private Map<MemberAndRoleIdBO, MemberFeignRightDetailVO> getMemberRightMap(Long memberId, Long roleId, List<ActivityGoodsSubsidiaryDO> activityGoodsSubsidiaryList) {
        Map<MemberAndRoleIdBO, MemberFeignRightDetailVO> memberRightMap = new HashMap<>();
        // 会员id角色id去重
        List<MemberFeignUpperMemberVO> upperMemberVOList = activityGoodsSubsidiaryList.stream()
                .map(e -> {
                    MemberAndRoleIdBO memberAndRoleIdBO = new MemberAndRoleIdBO();
                    memberAndRoleIdBO.setMemberId(e.getMemberId());
                    memberAndRoleIdBO.setRoleId(e.getRoleId());
                    return memberAndRoleIdBO;
                })
                .distinct()
                .map(e -> {
                    MemberFeignUpperMemberVO upperMemberVO = new MemberFeignUpperMemberVO();
                    upperMemberVO.setUpperMemberId(e.getMemberId());
                    upperMemberVO.setUpperRoleId(e.getRoleId());
                    return upperMemberVO;
                })
                .collect(Collectors.toList());

        MemberFeignBatchVO memberFeignBatchVO = new MemberFeignBatchVO();
        memberFeignBatchVO.setMemberId(memberId);
        memberFeignBatchVO.setRoleId(roleId);
        memberFeignBatchVO.setUpperMembers(upperMemberVOList);

        Wrapper<List<MemberFeignRightDetailVO>> listWrapper = memberFeignService.batchMemberPriceRight(memberFeignBatchVO);
        if (ResponseCode.SUCCESS.getCode() == listWrapper.getCode()) {
            memberRightMap = listWrapper.getData().stream().collect(Collectors.toMap(e -> new MemberAndRoleIdBO(e.getUpperMemberId(), e.getUpperRoleId()), e -> e, (e1, e2) -> e2));
        }

        return memberRightMap;
    }
}
